package com.aaa.aop;

import com.aaa.annotation.MyAnnotation;
import com.aaa.entity.OperLog;
import com.aaa.entity.Staff;
import com.aaa.mapper.OperLogMapper;
import com.aaa.vo.R;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

@Component //表示该类交于spring容器管理
@Aspect //表示该类为切面类
public class LogAspectj {
     //2.定义切点.
    //第一个*:表示返回类型，
    //第二个*:表示所有类
    //第三个*: 表示所有的方法
    //..:表示任意参数
//     @Pointcut("execution(* com.aaa.controller.StaffController.login(..))||execution(* com.aaa.controller.DeptController.list(..))")  //execution使用路径方式
//     public void pointcut(){}
    @Pointcut("@annotation(com.aaa.annotation.MyAnnotation)") //注解的类型
    public void pointcut(){}

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private HttpSession session;
    @Autowired
    private OperLogMapper operLogMapper;
    //环绕通知---把上面这些通知结合到一块。
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint){
        //1.创建日志对象
        OperLog operLog=new OperLog();
        //获取业务类型
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method2 = signature.getMethod();//获取被代理的方法对象
        MyAnnotation annotation = method2.getAnnotation(MyAnnotation.class);//获取被代理方法对象上的注解对象
        String name = annotation.name(); //获取注解上name属性的值
        operLog.setBusinesstype(name);
        //2.获取被代理的接口方法名
        String method = joinPoint.getSignature().getName();
        operLog.setMethod(method);
        //3.获取请求方式
        String method1 = request.getMethod();
        operLog.setRequestmethod(method1);
        //4.获取操作人的姓名
        Staff staff = (Staff) session.getAttribute("staff");
        operLog.setOpername(staff.getStaffname());
        //5.获取请求的地址
        String operUrl = request.getRequestURI();
        operLog.setOperurl(operUrl);
        //6.获取ip地址
        String remoteAddr = request.getRemoteAddr();
        operLog.setOperip(remoteAddr);
        //7. 获取被代理方法的参数
        Object[] args = joinPoint.getArgs();
        String s = Arrays.toString(args);
        operLog.setOperparam(s);

        //8.操作时间
        operLog.setOpertime(new Date());
        try{
            Object proceed = joinPoint.proceed(); //
            operLog.setJsonresult(proceed.toString());
            //9.设置状态
            operLog.setStatus(0);
            return proceed;
        }catch (Throwable throwable){
            //设置状态
            operLog.setStatus(1);
            throwable.printStackTrace();
        }finally {
            operLogMapper.insert(operLog);
        }
        return null;
    }
    //
}
/**
 * 1.引入spring-aspectj依赖
 * 2.定义切面类。 @Component @Aspect标记该类为切面类
 *     1.定义切点: @Pointcut("execution(* com.aaa.controller.StaffController.*(..))")
 *     2.处理： 通知类型:
 * 3. 开启切面注解驱动.<aop:aspectj-autoproxy/>
 */
